﻿using System.ServiceModel;
using Stimulus360.Models.Data;
using System.Collections.Generic;
using Stimulus360.Models.Data.CustomTypes;

namespace Stimulus360.Services.Interfaces
{
    /// <summary>
    ///     This interface is used to interact with the IDataRepository to perform
    ///     to perform logical and CRUD operations on the Idea entity.
    /// </summary>
    [ServiceContract]    
    public interface IIdeaService
    {
        /// <summary>
        ///     Method to get New Ideas 
        /// </summary>
        /// <param name="pageNo">
        ///     The Page number being displayed on the screen.
        /// </param>
        /// <param name="pageSize">
        ///     The number of ideas being shown in the screen.
        /// </param>
        /// <returns>
        ///     A Paginated List of New Ideas based on the page number and pagesize
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        PaginatedCollection<Idea> GetNew(string pageNo, string pageSize);

        /// <summary>
        ///     Method to get all New Ideas 
        /// </summary>
        /// <returns>
        ///     A List all of New Ideas
        /// </returns>
        IEnumerable<Idea> GetNew();

        /// <summary>
        ///     Method to get Idea details based on idea Id
        /// </summary>
        /// <param name="ideaId">
        ///     The idea Id for which Idea object is to be retrieved
        /// </param>
        /// <returns>
        ///     Idea object for the given IdeaId
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        Idea FindById(string ideaId);

        /// <summary>
        ///     Method to get a list of feedback for the given idea.
        /// </summary>
        /// <param name="ideaId">
        ///     IdeaID for the Idea for which the feedback is to be retrieved
        /// </param>
        /// <param name="pageNo">
        ///     The Page number being displayed on the screen.
        /// </param>
        /// <param name="pageSize">
        ///     The number of feedbacks being shown in the screen.
        /// </param>
        /// <returns>
        ///     A Paginated List of feedback based on the page number and pagesize
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        PaginatedCollection<IdeaRating> GetFeedback(string ideaId, string pageNo, string pageSize);

        /// <summary>
        ///     Method to add feedback for a given Idea
        /// </summary>
        /// <param name="feedback">
        ///     The feedback to be added
        /// </param>      
        /// <remarks>
        ///     Input parameter type will need to change if method is exposed as REST.
        ///     also User Authentication will need to be implemented
        /// </remarks>
        void AddFeedback(IdeaRating feedback);

        /// <summary>
        ///     Method to get a list of ideas in the given category
        /// </summary>
        /// <param name="category">
        ///     The category Id for the given category
        /// </param>
        /// <param name="pageNo">
        ///     The Page number being displayed on the screen.
        /// </param>
        /// <param name="pageSize">
        ///     The number of ideas being shown in the screen.
        /// </param>
        /// <returns>
        ///     A Paginated List of  Ideas for the given category 
        ///     based on the page number and pagesize
        /// </returns>   
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        PaginatedCollection<Idea> FindInCategory(string category, string pageNo, string pageSize);

        /// <summary>
        ///     Method to find Ideas based on teh given search criteria.
        /// </summary>
        /// <param name="searchCriteria">
        ///     String representing the type of search criteria: ByStatus,ByDate,ByRanking
        /// </param>
        /// <param name="query">
        ///     Search string to be deciphered based on the search criteria.
        /// </param>
        /// <param name="pageNo">
        ///     The Page number being displayed on the screen.
        /// </param>
        /// <param name="pageSize">
        ///     The number of ideas being shown in the screen.
        /// </param>
        /// <returns>
        ///     A Paginated List of  Ideas for the givens earch criteria
        ///     based on the page number and pagesize
        /// </returns>   
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        PaginatedCollection<Idea> Search(string searchCriteria, string query, string pageNo, string pageSize);

        /// <summary>
        ///     Method to add a new Idea to the system.
        /// </summary>
        /// <param name="idea">
        ///     Idea to be added.
        /// </param>
        /// <remarks>
        ///     Input parameter type will need to change if method is exposed as REST.
        ///     also User Authentication will need to be implemented
        /// </remarks>
        void Add(Idea idea);
       
        /// <summary>
        ///     Method to get list of ideas related to the given idea
        /// </summary>
        /// <param name="ideaId">
        ///     IdeaID for which related list is to be retrieved
        /// </param>
        /// <returns>
        ///     List of related ideas.
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        ICollection<ProjectSummary> GetRelatedProjects(string ideaId);

        /// <summary>
        ///     This method is used to get the User's feedback for a specific Idea
        /// </summary>
        /// <param name="ideaId">
        ///     IdeaID for which feedback is to be retrieved.
        /// </param>
        /// <param name="userName">
        ///     User whose feedback is to be retrieved
        /// </param>
        /// <returns>
        ///     User Feedback for the given idea.
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        IdeaRating GetFeedback(string userName, string ideaId);

        /// <summary>
        ///    Method used for retrieving related ideas.
        /// </summary>
        /// <returns>
        ///     List of Most related Ideas.
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        ICollection<Idea> GetRelated(string ideaId);

        /// <summary>
        ///    Method used for RSS Feeds to get list of most popular ideas.
        /// </summary>
        /// <returns>
        ///     List of Most popular Ideas.
        /// </returns>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        IEnumerable<Idea> GetTopN(string topN);

        #region For Sync
        /// <summary>
        ///     This method is used to get the Popular Ideas to be
        ///     synced with the CRM DB
        /// </summary>
        /// <returns>
        ///     List of popular Ideas
        /// </returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
            Justification = "Method use is appropriate considering complexity and logic http://msdn.microsoft.com/en-us/library/bzwdh01d(VS.71).aspx#cpconpropertyusageguidelinesanchor1")]
        IEnumerable<Idea> GetPopular();

        /// <summary>
        ///     This method is used to update the status of the given idea
        /// </summary>
        /// <param name="idea">
        ///     The idea to be updated
        /// </param>
        /// <param name="status">
        ///     The new status to be set
        /// </param>
        /// <remarks>
        ///     Input parameter type will need to change if method is exposed as REST
        /// </remarks>
        void UpdateStatus(Idea idea, IdeaStatus status);

        /// <summary>
        ///     This method is called when an idea is accepted to form a project
        /// </summary>
        /// <param name="idea">
        ///     The Idea which has been accepted
        /// </param>
        /// <param name="projectId">
        ///     The asssociated project Id
        /// </param>
        /// <remarks>
        ///     All parameters have been taken in string format to enable REST calls in the future
        /// </remarks>
        /// <remarks>
        ///     Input parameter type will need to change if method is exposed as REST
        /// </remarks>
         void Accept(Idea idea, string projectId);
        #endregion
    }
}
